{% extends "layout.html" %}
{% block title %}软件下载链接查询{% endblock %}

{% block head %}
<style>
    .filter-section { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; padding: 20px; background-color: #eaf3f9; border-radius: 8px; }
    .filter-group { display: flex; flex-direction: column; }
    .filter-group label { margin-bottom: 8px; font-weight: bold; color: #555; }
    .filter-group select { padding: 10px 15px; border: 1px solid #ccc; border-radius: 5px; font-size: 1rem; background-color: #fff; cursor: pointer; transition: border-color 0.2s ease-in-out; -webkit-appearance: none; -moz-appearance: none; appearance: none; background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007bff%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13%205.1L146.2%20202.7%2018.7%2074.5a17.6%2017.6%200%200%200-25.3%2023.6l137.9%20146.9c5.3%205.3%2013%205.3%2018.3%200l137.9-146.9a17.6%2017.6%200%200%200-13-30.2z%22%2F%3E%3C%2Fsvg%3E'); background-repeat: no-repeat; background-position: right 10px center; background-size: 12px; }
    .filter-group select:focus { border-color: #007bff; outline: none; box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25); }
    .links-list { list-style-type: none; padding: 0; }
    .links-list li { background-color: #fdfdfd; border: 1px solid #e0e0e0; border-radius: 8px; margin-bottom: 15px; padding: 15px 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); transition: transform 0.2s ease-in-out; }
    .links-list li:hover { transform: translateY(-3px); }
    .links-list li strong { color: #0056b3; }
    .links-list li .download-info { display: flex; align-items: center; flex-wrap: wrap; margin-top: 10px; }
    .links-list li .download-info .url-text { flex-grow: 1; font-size: 0.9em; color: #555; word-break: break-all; margin-right: 10px; }
    .links-list li .download-info button { background-color: #007bff; color: white; border: none; border-radius: 5px; padding: 8px 12px; cursor: pointer; font-size: 0.9em; transition: background-color 0.2s ease; white-space: nowrap; }
    .links-list li .download-info button:hover { background-color: #0056b3; }
    .pip-mirrors-section { background-color: #eaf9e0; border: 1px solid #d4edda; border-radius: 8px; padding: 20px; margin-top: 30px; }
    .pip-mirrors-list { list-style-type: none; padding: 0; }
    .pip-mirrors-list li { margin-bottom: 15px; }
    .pip-mirrors-list li strong { color: #28a745; display: block; margin-bottom: 5px; }
    .pip-mirrors-list .command-container { display: flex; align-items: center; gap: 10px; }
    .pip-mirrors-list li pre { flex-grow: 1; background-color: #f8f8f8; border: 1px solid #ddd; padding: 10px; border-radius: 5px; overflow-x: auto; font-size: 0.9em; color: #333; white-space: pre-wrap; margin: 0; }
    .pip-mirrors-list li button { background-color: #28a745; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-size: 0.9em; transition: background-color 0.2s ease; }
    .pip-mirrors-list li button:hover { background-color: #218838; }
    #loading, #error-message { text-align: center; font-size: 1.1rem; padding: 20px; border-radius: 8px; margin-top: 20px; }
    #loading { background-color: #e0f7fa; color: #007bb3; border: 1px solid #b2ebf2; }
    #error-message { background-color: #ffebee; color: #d32f2f; border: 1px solid #ef9a9a; }
    .hidden { display: none; }
</style>
{% endblock %}

{% block content %}
<h1>软件下载链接查询</h1>

<div class="filter-section">
    <div class="filter-group">
        <label for="software-select">选择软件:</label>
        <select id="software-select"></select>
    </div>
    <div class="filter-group">
        <label for="os-select">选择操作系统:</label>
        <select id="os-select"></select>
    </div>
    <div class="filter-group" id="py-version-group">
        <label for="py-version-select">选择 Python 版本:</label>
        <select id="py-version-select"></select>
    </div>
    <div class="filter-group" id="version-group">
        <label for="version-select">选择软件版本:</label>
        <select id="version-select"></select>
    </div>
    <div class="filter-group">
        <label for="source-select">选择来源:</label>
        <select id="source-select"></select>
    </div>
</div>

<h2 style="margin-top: 30px;">下载链接</h2>
<div id="loading" class="hidden">加载配置中...</div>
<div id="error-message" class="hidden"></div>
<ul id="links-list" class="links-list"></ul>
<p id="no-links-message" class="hidden">无可用下载链接，请调整筛选条件。</p>

<h2 style="margin-top: 30px;">PyPI 镜像配置</h2>
<div class="pip-mirrors-section">
    <ul id="pip-mirrors-list" class="pip-mirrors-list"></ul>
</div>
{% endblock %}

{% block scripts %}
<script>
    const API_BASE_URL = '/api';
    let allOptions = { softwares: [], os_types: [], sources: [], software_specific: {} };
    let selectedSoftware = '', selectedOs = '', selectedPyVersion = '', selectedVersion = '', selectedSource = '';
    const softwareSelect = document.getElementById('software-select');
    const osSelect = document.getElementById('os-select');
    const pyVersionSelect = document.getElementById('py-version-select');
    const versionSelect = document.getElementById('version-select');
    const sourceSelect = document.getElementById('source-select');
    const pyVersionGroup = document.getElementById('py-version-group');
    const versionGroup = document.getElementById('version-group');
    const linksList = document.getElementById('links-list');
    const pipMirrorsList = document.getElementById('pip-mirrors-list');
    const loadingDiv = document.getElementById('loading');
    const errorMessageDiv = document.getElementById('error-message');
    const noLinksMessage = document.getElementById('no-links-message');

    function showLoading() { loadingDiv.classList.remove('hidden'); errorMessageDiv.classList.add('hidden'); linksList.innerHTML = ''; noLinksMessage.classList.add('hidden'); }
    function hideLoading() { loadingDiv.classList.add('hidden'); }
    function showErrorMessage(message) { errorMessageDiv.textContent = message; errorMessageDiv.classList.remove('hidden'); hideLoading(); linksList.innerHTML = ''; noLinksMessage.classList.add('hidden'); }
    function hideErrorMessage() { errorMessageDiv.classList.add('hidden'); }

    function populateSelect(selectElement, optionsArray, selectedValue) {
        selectElement.innerHTML = '';
        if (!optionsArray || optionsArray.length === 0) {
            const option = document.createElement('option');
            option.value = '';
            option.textContent = '无可用';
            selectElement.appendChild(option);
            selectElement.disabled = true;
            return;
        }
        selectElement.disabled = false;
        let foundSelected = false;
        optionsArray.forEach(optionValue => {
            const option = document.createElement('option');
            option.value = optionValue;
            option.textContent = optionValue;
            if (optionValue === selectedValue) {
                option.selected = true;
                foundSelected = true;
            }
            selectElement.appendChild(option);
        });
        if (!foundSelected && optionsArray.length > 0) {
            selectElement.selectedIndex = 0;
            if (selectElement === softwareSelect) selectedSoftware = selectElement.value;
            else if (selectElement === osSelect) selectedOs = selectElement.value;
            else if (selectElement === pyVersionSelect) selectedPyVersion = selectElement.value;
            else if (selectElement === versionSelect) selectedVersion = selectElement.value;
            else if (selectElement === sourceSelect) selectedSource = selectElement.value;
        } else if (foundSelected) {
            if (selectElement === softwareSelect) selectedSoftware = selectedValue;
            else if (selectElement === osSelect) selectedOs = selectedValue;
            else if (selectElement === pyVersionSelect) selectedPyVersion = selectedValue;
            else if (selectElement === versionSelect) selectedVersion = selectedValue;
            else if (selectElement === sourceSelect) selectedSource = selectedValue;
        }
    }

    async function fetchOptionsData() {
        try {
            const response = await fetch(`${API_BASE_URL}/options`);
            if (!response.ok) throw new Error(`HTTP 错误！状态：${response.status}`);
            allOptions = await response.json();
        } catch (error) {
            console.error("获取选项失败:", error);
            throw error;
        }
    }

    async function copyToClipboard(text, button) {
        const originalText = button.textContent;
        try {
            // 优先使用 Clipboard API，因为它更现代且安全
            if (navigator.clipboard && window.isSecureContext) {
                await navigator.clipboard.writeText(text);
            } else {
                // 兼容旧版浏览器
                const textarea = document.createElement('textarea');
                textarea.value = text;
                textarea.style.position = 'fixed';
                textarea.style.left = '-9999px';
                document.body.appendChild(textarea);
                textarea.focus();
                textarea.select();
                document.execCommand('copy');
                document.body.removeChild(textarea);
            }
            button.textContent = '已复制!';
            setTimeout(() => {
                button.textContent = originalText;
            }, 2000);
        } catch (err) {
            console.error('复制失败:', err);
            button.textContent = '复制失败';
             setTimeout(() => {
                button.textContent = originalText;
            }, 2000);
        }
    }

    async function fetchPipMirrors() {
        try {
            const response = await fetch(`${API_BASE_URL}/pip-mirrors`);
            if (!response.ok) throw new Error(`HTTP 错误！状态：${response.status}`);
            const pipMirrors = await response.json();
            pipMirrorsList.innerHTML = '';
            if (Object.keys(pipMirrors).length > 0) {
                for (const [name, command] of Object.entries(pipMirrors)) {
                    const li = document.createElement('li');
                    const commandText = command.replace(/https?:\/\//, 'https://'); // 优先使用 https
                    
                    li.innerHTML = `
                        <strong>${name.charAt(0).toUpperCase() + name.slice(1)} 镜像 (HTTPS):</strong>
                        <div class="command-container">
                            <pre><code>${commandText}</code></pre>
                            <button class="copy-btn">复制</button>
                        </div>
                    `;
                    li.querySelector('.copy-btn').onclick = (e) => copyToClipboard(commandText, e.target);
                    pipMirrorsList.appendChild(li);
                }
            } else {
                pipMirrorsList.innerHTML = '<li>无可用 PyPI 镜像配置。</li>';
            }
        } catch (error) {
            console.error("获取pip镜像失败:", error);
        }
    }

    async function fetchLinks() {
        if (!selectedSoftware || !selectedOs || (!selectedPyVersion && !selectedVersion) || !selectedSource) {
            linksList.innerHTML = '';
            noLinksMessage.classList.remove('hidden');
            return;
        }
        showLoading();
        hideErrorMessage();
        try {
            const params = new URLSearchParams({
                software: selectedSoftware,
                os: selectedOs,
                source: selectedSource,
            });
            if (selectedPyVersion) {
                params.append('py_version', selectedPyVersion);
            } else if (selectedVersion) {
                params.append('version', selectedVersion);
            }
            const response = await fetch(`${API_BASE_URL}/links?${params.toString()}`);
            if (!response.ok) throw new Error(`HTTP 错误！状态：${response.status}`);
            const links = await response.json();
            linksList.innerHTML = '';
            if (links.length > 0) {
                noLinksMessage.classList.add('hidden');
                links.forEach((link, index) => {
                    const li = document.createElement('li');
                    li.innerHTML = `
                        <strong>软件:</strong> ${link.software} <br />
                        <strong>版本:</strong> ${link.display_version} 
                        ${link.py_version ? `(Python ${link.py_version})` : ''} 
                        ${link.version && !link.py_version ? `(${link.version})` : ''} <br />
                        <strong>操作系统:</strong> ${link.os} ${link.arch ? `(${link.arch})` : ''} ${link.type ? `(${link.type})` : ''} <br />
                        <strong>来源:</strong> ${link.source} <br />
                        <div class="download-info">
                            <span class="url-text">${link.url}</span>
                            <button class="copy-btn">复制链接</button>
                        </div>
                    `;
                    li.querySelector('.copy-btn').onclick = (e) => copyToClipboard(link.url, e.target);
                    linksList.appendChild(li);
                });
            } else {
                noLinksMessage.classList.remove('hidden');
            }
        } catch (error) {
            console.error("获取链接失败:", error);
            showErrorMessage("获取下载链接失败。请检查您的筛选条件。");
        } finally {
            hideLoading();
        }
    }

    function updateVersionSelectors() {
        const specificOptions = allOptions.software_specific[selectedSoftware];
        const showPyVersion = ['miniconda', 'anaconda', 'python_idle'].includes(selectedSoftware);
        const showGenericVersion = ['anaconda', 'pycharm', 'vscode'].includes(selectedSoftware);
        pyVersionGroup.classList.toggle('hidden', !showPyVersion);
        versionGroup.classList.toggle('hidden', !showGenericVersion);
        if (showPyVersion && specificOptions) {
            populateSelect(pyVersionSelect, specificOptions.py_versions, selectedPyVersion);
        } else {
            selectedPyVersion = '';
            pyVersionSelect.innerHTML = '';
        }
        if (showGenericVersion && specificOptions) {
            populateSelect(versionSelect, specificOptions.versions, selectedVersion);
        } else {
            selectedVersion = '';
            versionSelect.innerHTML = '';
        }
        if (specificOptions) {
            populateSelect(osSelect, specificOptions.os_types, selectedOs);
            populateSelect(sourceSelect, specificOptions.sources, selectedSource);
        }
    }

    softwareSelect.addEventListener('change', () => {
        selectedSoftware = softwareSelect.value;
        const specificOptions = allOptions.software_specific[selectedSoftware];
        if (specificOptions) {
             if (selectedSoftware === 'python_idle') {
                let compatible310Versions = specificOptions.py_versions.filter(v => v.startsWith('3.10.') && parseInt(v.split('.')[2]) < 10);
                if (compatible310Versions.length > 0) {
                    compatible310Versions.sort((a, b) => parseInt(b.split('.')[2]) - parseInt(a.split('.')[2]));
                    selectedPyVersion = compatible310Versions[0];
                } else {
                    selectedPyVersion = specificOptions.py_versions[0] || '';
                }
                if (specificOptions.sources.includes('aliyun')) {
                    selectedSource = 'aliyun';
                } else if (specificOptions.sources.includes('official')) {
                    selectedSource = 'official';
                } else {
                    selectedSource = specificOptions.sources[0] || '';
                }
                if (specificOptions.os_types.includes('windows')) {
                    selectedOs = 'windows';
                } else {
                    selectedOs = specificOptions.os_types[0] || '';
                }
            } else {
                selectedPyVersion = specificOptions.py_versions[0] || '';
                selectedVersion = specificOptions.versions[0] || '';
                selectedOs = specificOptions.os_types[0] || '';
                if (specificOptions.sources.includes('tsinghua')) {
                    selectedSource = 'tsinghua';
                } else if (specificOptions.sources.includes('aliyun')) {
                    selectedSource = 'aliyun';
                } else {
                    selectedSource = specificOptions.sources[0] || '';
                }
            }
        } else {
            selectedPyVersion = '';
            selectedVersion = '';
            selectedOs = '';
            selectedSource = '';
        }
        updateVersionSelectors();
        fetchLinks();
    });

    osSelect.addEventListener('change', () => { selectedOs = osSelect.value; fetchLinks(); });
    pyVersionSelect.addEventListener('change', () => { selectedPyVersion = pyVersionSelect.value; fetchLinks(); });
    versionSelect.addEventListener('change', () => { selectedVersion = versionSelect.value; fetchLinks(); });
    sourceSelect.addEventListener('change', () => { selectedSource = sourceSelect.value; fetchLinks(); });

    document.addEventListener('DOMContentLoaded', async () => {
        showLoading();
        try {
            await fetchOptionsData();
            selectedSoftware = 'python_idle';
            populateSelect(softwareSelect, allOptions.softwares, selectedSoftware);
            const specificIdleOptions = allOptions.software_specific['python_idle'];
            if (specificIdleOptions) {
                if (specificIdleOptions.os_types.includes('windows')) {
                    selectedOs = 'windows';
                } else {
                    selectedOs = specificIdleOptions.os_types[0] || '';
                }
                populateSelect(osSelect, specificIdleOptions.os_types, selectedOs);
                let compatible310Versions = specificIdleOptions.py_versions.filter(v => v.startsWith('3.10.') && parseInt(v.split('.')[2]) < 10);
                if (compatible310Versions.length > 0) {
                    compatible310Versions.sort((a, b) => parseInt(b.split('.')[2]) - parseInt(a.split('.')[2]));
                    selectedPyVersion = compatible310Versions[0];
                } else if (specificIdleOptions.py_versions.length > 0) {
                    selectedPyVersion = specificIdleOptions.py_versions[0];
                } else {
                    selectedPyVersion = '';
                }
                populateSelect(pyVersionSelect, specificIdleOptions.py_versions, selectedPyVersion);
                if (specificIdleOptions.sources.includes('aliyun')) {
                    selectedSource = 'aliyun';
                } else if (specificIdleOptions.sources.includes('official')) {
                    selectedSource = 'official';
                } else {
                    selectedSource = specificIdleOptions.sources[0] || '';
                }
                populateSelect(sourceSelect, specificIdleOptions.sources, selectedSource);
            }
            updateVersionSelectors();
            await fetchPipMirrors();
            await fetchLinks();
        } catch (error) {
            console.error("应用初始化失败:", error);
            showErrorMessage("应用初始化失败。请检查后端服务是否运行，并确保 software_links.json 文件正确。");
        } finally {
            hideLoading();
        }
    });
</script>
{% endblock %}